package com.winchain.chainbill.bill.biz.receive.rx;

import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.bee.persistence.transaction.Transaction;
import com.shell.bee.persistence.transaction.TransactionUtil;
import com.shell.framework.command.ChainBase;
import com.shell.framework.command.CommandContext;
import com.shell.framework.rx.OnErrorNotImplementedSubscriber;
import com.winchain.chainbill.bill.base.po.CbRcv;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.receive.cmd.BillRcvMsgCmd;
import com.winchain.chainbill.bill.biz.receive.cmd.BillRcvRjctCrdtCmd;
import com.winchain.chainbill.bill.biz.receive.vo.BillRcv;
import com.winchain.chainbill.bill.biz.send.cmd.BillMoveCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillOptCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillSndInvoinceRejectICmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillTimeoutCmd;
import com.winchain.chainbill.bill.biz.send.rx.BatchBillEvent;
import com.winchain.chainbill.bill.biz.send.vo.BatchBillStats;
import com.winchain.chainbill.chain.callback.cmd.SyncConfirmCmd;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class BillRcvArpvRjctSubscriber extends OnErrorNotImplementedSubscriber<BatchBillEvent<BillRcv, CbRcv>> {
	private final Log logger = LogFactory.getLog(getClass());
	@Autowired
	private BillOptCmd<CbRcv> billOptCmd;
	@Autowired
	private BillMoveCmd<CbRcv> billMoveCmd;
	@Autowired
	private BillRcvMsgCmd billRcvMsgCmd;
	@Autowired
	private BillRcvRjctCrdtCmd billRcvRjctCrdtCmd;
	@Autowired
	private BillTimeoutCmd<CbRcv> billTimeoutCmd;
	@Autowired
	private BillSndInvoinceRejectICmd<CbRcv> billSndInvoinceRejectICmd;
	@Autowired
	private SyncConfirmCmd<Bill<CbRcv>> syncConfirmCmd;

	public void onApplicationEvent(final BatchBillEvent<BillRcv, CbRcv> t) {
		List<BillRcv> records = t.getRecs();
		BatchBillStats<CbRcv> stats = t.getStats();
		final Bill<CbRcv> bill = new Bill();
		final List<AcctTxRec> acctTxRecs = new ArrayList();
		for (final BillRcv record : records) {
			try {
				TransactionUtil.execute(new Transaction() {
					public void doInTransaction() {
						bill.setRec(record.getRec());
						bill.setSource(record.getRcv());
						CommandContext<Bill<CbRcv>> context = new CommandContext();
						context.setSource(bill);
						context.setValue("Operation", t.getOperation());
						context.setValue("TimeoutOperation", t.getTimeoutOpt());

						context.setValue("bizType", "rc_aprv_rj");

						ChainBase<Bill<CbRcv>> crb = new ChainBase();
						crb.add(BillRcvArpvRjctSubscriber.this.billTimeoutCmd);
						crb.add(BillRcvArpvRjctSubscriber.this.billOptCmd);
						crb.add(BillRcvArpvRjctSubscriber.this.billMoveCmd);
						crb.add(BillRcvArpvRjctSubscriber.this.billRcvRjctCrdtCmd);
						crb.add(BillRcvArpvRjctSubscriber.this.billSndInvoinceRejectICmd);
						crb.add(BillRcvArpvRjctSubscriber.this.syncConfirmCmd);
						crb.add(BillRcvArpvRjctSubscriber.this.billRcvMsgCmd);
						crb.execute(context);
						acctTxRecs.add((AcctTxRec) context.getValue("acctTxRec"));
					}
				}, new int[0]);

				t.setValue("acctTxRecs", acctTxRecs);
				stats.addPassedRecord(bill);
			} catch (Exception e) {
				e.printStackTrace();
				this.logger.error("Rcv aprv rjct error!", e);
				stats.addAbnormalRecord(bill);
				stats.addAbnormalMsg(e.getMessage());
			}
		}
	}
}
